Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sessions): updating the cosign signing and the bundler #715

Merged
merged 2 commits into from
Jul 23, 2024

Conversation

geekbrother
Copy link
Contributor

@geekbrother geekbrother commented Jul 22, 2024

Description

This PR is making the following changes to the Co-Signing endpoint:

  • Changing the signature to comply with the Ethereum signing flow, using the LocalWallet and packing the signature.
  • Changing the bundler function and variables to not be sticked to the Biconomy (BICONOMY_BUNDLER_* -> BUNDLER_*) and changing the default bundler to the Pimlico.
  • Changing the request userOperation struct to be v07 from v06 to proper calculation of the packed UserOperation.
  • Adding calculation of the additional fields (paymaster, factory) for the packed UserOperation structure builder to support paymasters.
  • Multiple fixes and crypto utils functions refactors.

How Has This Been Tested?

This flow was tested manually with the testing dapp cosigning flow.

Due Diligence

  • Breaking change
  • Requires a documentation update
  • Requires a e2e/integration test update

@@ -466,8 +466,7 @@ impl JsonRpcClient for SelfProvider {
let id = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time should't go backwards")
.as_millis()
.to_string();
.as_secs();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a shared JsonRPC request struct and the bundler complained that the Id should be the int.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of that expect outside of initialization code. Would you rather make it an error instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. We are using this in many places so this should be a follow-up. #716 was created for this. Thanks for catching this!

pub fn add_eip191(message: &str) -> String {
format!("\x19Ethereum Signed Message:\n{}{}", message.len(), message)
/// Convert message to EIP-191 compatible format
pub fn to_eip191_message(message: &[u8]) -> Vec<u8> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing this function to use bytes instead of Strings, to remove double conversions since we are using bytes for the keccak256 hashing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice refactor

}

/// Pack signature into a single byte array to Ethereum compatible format
pub fn pack_signature(unpacked: &EthSignature) -> Bytes {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Packing of s,r,v of the ecdsa signature into the Ethereum format.

// Update the userOp with the signature
user_op.signature = get_signature_result;
// Todo: remove this debug line before production stage
info!("UserOpPacked final JSON: {:?}", serde_json::json!(user_op));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need this userOp json to trace it in case of issues for the alpha version. Since there is no any traffic to this endpoint, there shouldn't be a problem with the Cloudwatch cost.

@geekbrother geekbrother marked this pull request as ready for review July 22, 2024 12:12
.context
.permissions_context
.clone()
.trim_start_matches("0x"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid this trim by having the original data or the client-facing API not provide this? Should be normalized one way or the other vs being permissive here and trimming it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The client sends this as a String representation of eth hex bytes "0x...", to pass this to the contract we need to convert this representation into ethers::Bytes as the contract expects the Bytes format. To do this we need to hex decode it and trim 0x to decode. That's why we need to trim 0x when converting it.

/// Convert message to EIP-191 compatible format
pub fn to_eip191_message(message: &[u8]) -> Vec<u8> {
let prefix = format!("\x19Ethereum Signed Message:\n{}", message.len());
let mut eip191_message = Vec::with_capacity(prefix.len() + message.len());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice using with_capacity

r.to_big_endian(&mut r_bytes);
s.to_big_endian(&mut s_bytes);
// Pack r, s, and v into a single byte array
let mut packed_signature = Vec::with_capacity(65);
Copy link
Member

@chris13524 chris13524 Jul 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-documenting where what the size is based on

Suggested change
let mut packed_signature = Vec::with_capacity(65);
let mut packed_signature = Vec::with_capacity(r_bytes.len() + s_bytes.len() + 1);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense! Changed it. Thanks.

Copy link
Member

@chris13524 chris13524 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

We'll need tests here soon!

@geekbrother
Copy link
Contributor Author

We'll need tests here soon!

Totally! I'm testing by the manual run of the integration test now, since we need a gas to make the full flow.
I'm thinking to reduce the test to just the validation/simulation step for the CI/CD integration tests.

@geekbrother geekbrother force-pushed the fix/co-signer_signature_bundler_updates branch from 47d9a34 to ee8a1fa Compare July 23, 2024 11:01
@geekbrother geekbrother merged commit d91a40f into master Jul 23, 2024
16 checks passed
@geekbrother geekbrother deleted the fix/co-signer_signature_bundler_updates branch July 23, 2024 11:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants